package com.beemans.topon.ads2;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;

import com.anythink.banner.api.ATBannerListener;
import com.anythink.banner.api.ATBannerView;
import com.anythink.core.api.ATAdConst;
import com.anythink.core.api.ATAdInfo;
import com.anythink.core.api.ATAdStatusInfo;
import com.anythink.core.api.AdError;

import java.util.HashMap;
import java.util.Map;

public class BannerAdvert extends BaseAdvert implements ATBannerListener {
    @NonNull
    private final BannerAdvertConfig advertConfig;
    @Nullable
    private ViewGroup viewGroup;
    @Nullable
    private ATBannerView atBannerView;
    @Nullable
    private BannerAdvertCallback advertCallback;

    private int advertWidth;
    private int advertHeight;
    private boolean isAdvertLoaded;
    private boolean isAdvertLoadFailed = false;

    public BannerAdvert(
            @NonNull LifecycleOwner lifecycleOwner,
            @NonNull ViewGroup viewGroup,
            @NonNull BannerAdvertConfig advertConfig,
            @Nullable BannerAdvertCallback advertCallback
    ) {
        this.advertConfig = advertConfig;
        this.viewGroup = viewGroup;
        this.advertCallback = advertCallback;

        final Context context = AdvertLifeUtils.getContext(lifecycleOwner);
        if (context == null) {
            return;
        }

        atBannerView = new ATBannerView(context);
        atBannerView.setPlacementId(advertConfig.getPlacementId());
        atBannerView.setBannerAdListener(this);

        if (viewGroup.getVisibility() != View.VISIBLE) {
            viewGroup.setVisibility(View.VISIBLE);
        }

        viewGroup.post(() -> {
            final float whRatio = advertConfig.getAdvertWHRatio();
            advertWidth = viewGroup.getWidth();
            advertHeight = (int) (advertWidth / whRatio);

            final Map<String, Object> localMap = new HashMap<>();
            localMap.put(ATAdConst.KEY.AD_WIDTH, advertWidth);
            localMap.put(ATAdConst.KEY.AD_HEIGHT, advertHeight);

            if (atBannerView != null) {
                atBannerView.setLocalExtra(localMap);

                final ViewParent viewParent = atBannerView.getParent();
                if (viewParent instanceof ViewGroup) {
                    ((ViewGroup) viewParent).removeView(atBannerView);
                }

                viewGroup.removeAllViews();
                viewGroup.addView(atBannerView);
            }
        });

        AdvertLifeUtils.launchWhenDestroy(lifecycleOwner, this::onAdvertRelease);

        if (advertCallback != null) {
            advertCallback.onAdvertStart(this);
        }
    }

    /**
     * 广告是否正在加载
     */
    @Override
    public boolean isAdvertLoading() {
        if (atBannerView == null) {
            return false;
        }
        final ATAdStatusInfo atAdStatusInfo = atBannerView.checkAdStatus();
        return atAdStatusInfo != null && atAdStatusInfo.isLoading();
    }

    @Override
    public boolean isAdvertReady() {
        if (atBannerView == null) {
            return false;
        }
        final ATAdStatusInfo atAdStatusInfo = atBannerView.checkAdStatus();
        return atAdStatusInfo != null && atAdStatusInfo.isReady();
    }

    @Override
    public void onAdvertRelease() {
        super.onAdvertRelease();

        if (viewGroup != null) {
            viewGroup.removeAllViews();
            viewGroup = null;
        }
        if (atBannerView != null) {
            final ViewParent viewParent = atBannerView.getParent();
            if (viewParent instanceof ViewGroup) {
                ((ViewGroup) viewParent).removeView(atBannerView);
            }
            try {
                atBannerView.destroy();
            } catch (Throwable ignored) {
            }
            try {
                atBannerView.setBannerAdListener(null);
                atBannerView.setAdDownloadListener(null);
                atBannerView.setAdSourceStatusListener(null);
            } catch (Throwable ignored) {
            }
            atBannerView = null;
        }
        if (advertCallback != null) {
            advertCallback = null;
        }
    }

    /**
     * 加载广告
     */
    @Override
    protected void loadAdvert() {
        isAdvertLoaded = false;
        isAdvertLoadFailed = false;

        if (atBannerView == null) {
            return;
        }

        waitForAdvertToLoad(() -> {
            if (viewGroup == null) {
                return;
            }
            viewGroup.post(() -> {
                if (atBannerView != null) {
                    try {
                        atBannerView.loadAd();
                    } catch (Throwable throwable) {
                        onAdvertLoadFail(throwable.getMessage());
                    }
                }
            });
        });
    }

    private void onAdvertLoaded(boolean isAutoRefreshed) {
        if (isAdvertLoaded) return;
        isAdvertLoaded = true;

        if (isAutoRefreshed) {
            updateBannerViewHeight(advertWidth, advertHeight);
        }

        if (advertCallback != null) {
            advertCallback.onAdvertLoaded(this);
        }
    }

    private void onAdvertLoadFail(String adError) {
        if (isAdvertLoadFailed) return;
        isAdvertLoadFailed = true;

        if (advertCallback != null) {
            advertCallback.onAdvertLoadFail(this, adError);
        }
    }

    private void updateBannerViewHeight(int viewWidth, int viewHeight) {
        if (atBannerView == null) {
            return;
        }
        final ViewTreeObserver observer = atBannerView.getViewTreeObserver();
        if (!observer.isAlive()) {
            return;
        }
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                final ViewTreeObserver observer = atBannerView.getViewTreeObserver();
                if (observer.isAlive()) {
                    observer.removeOnGlobalLayoutListener(this);
                }

                final int bannerHeight = atBannerView.getHeight();
                int newViewHeight = viewHeight;
                if (bannerHeight > 0 && bannerHeight < viewHeight) {
                    newViewHeight = bannerHeight;
                }
                final FrameLayout.LayoutParams layoutParams
                        = new FrameLayout.LayoutParams(viewWidth, newViewHeight);
                atBannerView.setLayoutParams(layoutParams);
            }
        });
    }

    @Override
    public void onBannerLoaded() {
        onAdvertLoaded(false);
    }

    @Override
    public void onBannerFailed(AdError adError) {
        onAdvertLoadFail(adError != null ? adError.toString() : null);
    }

    @Override
    public void onBannerClicked(ATAdInfo atAdInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClicked(this, atAdInfo);
        }
    }

    @Override
    public void onBannerShow(ATAdInfo atAdInfo) {
        updateBannerViewHeight(advertWidth, advertHeight);

        if (advertCallback != null) {
            advertCallback.onAdvertShow(this, atAdInfo);
        }
    }

    @Override
    public void onBannerClose(ATAdInfo atAdInfo) {
        if (advertCallback != null) {
            advertCallback.onAdvertClose(this, atAdInfo);
        }
        if (advertConfig.isReleaseOnAdClose()) {
            onAdvertRelease();
        }
    }

    @Override
    public void onBannerAutoRefreshed(ATAdInfo atAdInfo) {
        onAdvertLoaded(true);

        if (advertCallback != null) {
            advertCallback.onAdvertShow(this, atAdInfo);
        }
    }

    @Override
    public void onBannerAutoRefreshFail(AdError adError) {
    }
}
